package org.design.log.util;

import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.experimental.UtilityClass;
import org.design.log.entity.ApiLog;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.util.*;

/**
 * ApiLogUtils
 *
 * @author 樊温军
 * @date 2025/6/23 上午8:50
 */
@UtilityClass
public class ApiLogUtils {
    public ApiLog getSysLog() {
        HttpServletRequest request = ((ServletRequestAttributes) Objects
                .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        ApiLog apiLog = new ApiLog();
        apiLog.setIp(getClientIP(request));
        apiLog.setRequestUri(URLUtil.getPath(request.getRequestURI()));
        apiLog.setMethod(request.getMethod());
        apiLog.setUserAgent(request.getHeader("user-agent"));
        apiLog.setParams(HttpUtil.toParams(request.getParameterMap()));
        Enumeration<String> headerNames = request.getHeaderNames();
        Iterator<String> iterator = headerNames.asIterator();
        Map<String, String> headerMap = new HashMap<>();
        while (iterator.hasNext()) {
            String header = iterator.next();
            headerMap.put(header, request.getHeader(header));
        }
        apiLog.setHeader(JSONUtil.toJsonStr(headerMap));
//        apiLog.setCreateBy();
        apiLog.setCreateTime(LocalDateTime.now());
        return apiLog;
    }

    private String getClientIP(HttpServletRequest request, String... otherHeaderNames) {
        String[] headers = new String[]{"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP",
                "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};
        if (ArrayUtil.isNotEmpty(otherHeaderNames)) {
            headers = ArrayUtil.addAll(headers, otherHeaderNames);
        }
        return getClientIPByHeader(request, headers);
    }

    private String getClientIPByHeader(HttpServletRequest request, String... headerNames) {
        String ip;
        for (String header : headerNames) {
            ip = request.getHeader(header);
            if (!NetUtil.isUnknown(ip)) {
                return NetUtil.getMultistageReverseProxyIp(ip);
            }
        }
        ip = request.getRemoteAddr();
        return NetUtil.getMultistageReverseProxyIp(ip);
    }
}
